﻿/*
 * KLF Headless Browser
 * Written by Kris Oye <kristianoye@gmail.com>
 * Copyright (C) 2011-2012.  All rights reserved.
 */
namespace KLF.Lib.Browser.DOM.TypedArray
{
    #region Using Statements

    using System;
    using System.Linq;
    using System.Collections;
    using System.Collections.Generic;

    #endregion

    public class ArrayBuffer : IArrayBuffer
    {
        #region Constructors

        private ArrayBuffer()
        {
        }

        public ArrayBuffer(long _size)
        {
            try
            {
                _Buffer = new byte[_size];
            }
            catch (OutOfMemoryException)
            {
                Console.WriteLine("ArrayBuffer failed to allocate {0} elements.", _size);
            }
        }

        public ArrayBuffer(IEnumerable<byte> _bufferIn)
        {
            _Buffer = _bufferIn.ToArray();
        }

        #endregion

        #region Attributes

        public int byteLength
        {
            get
            {
                return _Buffer.Length;
            }
        }

        internal virtual Byte[] _Buffer { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// Returns a new ArrayBuffer whose contents are a copy of this 
        /// ArrayBuffer's bytes from begin, inclusive, up to end, exclusive.
        /// If either begin or end is negative, it refers to an index from 
        /// the end of the array, as opposed to from the beginning.
        /// 
        /// If end is unspecified, the new ArrayBuffer contains all bytes 
        /// from begin to the end of this ArrayBuffer.
        /// 
        /// The range specified by the begin and end values is clamped to 
        /// the valid index range for the current array. If the computed
        /// length of the new ArrayBuffer would be negative, it is clamped
        /// to zero.
        /// </summary>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public IArrayBuffer slice(int begin)
        {
            return slice(begin, 0);
        }

        /// <summary>
        /// Returns a new ArrayBuffer whose contents are a copy of this 
        /// ArrayBuffer's bytes from begin, inclusive, up to end, exclusive.
        /// If either begin or end is negative, it refers to an index from 
        /// the end of the array, as opposed to from the beginning.
        /// 
        /// If end is unspecified, the new ArrayBuffer contains all bytes 
        /// from begin to the end of this ArrayBuffer.
        /// 
        /// The range specified by the begin and end values is clamped to 
        /// the valid index range for the current array. If the computed
        /// length of the new ArrayBuffer would be negative, it is clamped
        /// to zero.
        /// </summary>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public IArrayBuffer slice(int begin, int end)
        {
            int len = _Buffer.Length - begin;
            Byte[] buf = new Byte[len];

            Array.Copy(_Buffer, 
                begin, 
                buf, 
                0, 
                (end > begin ? end - begin : len));

            return new ArrayBuffer()
            {
                _Buffer = buf
            };
        }

        #endregion
    }
}
